package com.cheneyjoo.view;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cheneyjoo.base.Menu;
import com.cheneyjoo.model.RequestMessage;
import com.cheneyjoo.util.CheneyScanner;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ExamMenu extends Menu {
    public ExamMenu() {
    }

    public ExamMenu(Socket socket, PrintStream out, BufferedReader in) {
        super.setSocket(socket);
        super.setOut(out);
        super.setIn(in);
    }

    @Override
    public void menu() throws IOException {
        boolean isShowAll = true;
        while (true) {
            if (isShowAll) getExam();
            if (!isShowAll) isShowAll = true;
            System.out.println("------------------------------------------");
            System.out.println("--试题管理");
            System.out.print("      [1]新增试题");
            System.out.println("\t [2]修改试题");
            System.out.print("      [3]删除试题");
            System.out.println("      [4]查询试题");
            System.out.println("--考试管理");
            System.out.print("      [5]发布考试");
            System.out.println("\t [6]回收考试");
            System.out.print("      [7]查询成绩");
            System.out.println("\t[0]返回");
            System.out.println("请选择对应的功能编码：");
            System.out.println("------------------------------------------");
            String menu = CheneyScanner.reader.readLine();
            switch (menu) {
                case "1":
                    addQuestion();
                    break;
                case "2":
                    updateQuestion();
                    break;
                case "3":
                    deleteQuestion();
                    break;
                case "4":
                    isShowAll = false;
                    getQuestions();
                    break;
                case "5":
                    isShowAll = false;
                    releaseExam();
                    break;
                case "6":
                    isShowAll = false;
                    recoveryExam();
                    break;
                case "7":
                    isShowAll = false;
                    getExamAnswer();
                    break;
                default:
                    new ManagerMenu(super.getSocket(), super.getOut(), super.getIn()).menu();
                    return;
            }
        }
    }

    /**
     * 获取所有的试卷信息
     *
     * @throws IOException
     */
    private void getExam() throws IOException {
        RequestMessage rm = new RequestMessage("exam", "getExam", null);
        JSONObject result = getResponseResult(rm);
        Object content = result.get("content");
        System.out.println("------------------------------------------");
        if (content.getClass().equals(JSONArray.class)) {
            JSONArray exams = (JSONArray) content;
            System.out.println("ID\t试卷名称\t科目\t状态");
            for (Object exam : exams) {
                JSONObject o = (JSONObject) exam;
                System.out.println(o.get("id") + "\t" + o.get("examName") + "\t" + o.get("categoryName") + "\t" + (o.get("status").toString().equals("0") ? "未发布" : "已发布"));
            }
        }
    }

    /**
     * 根据状态获取试卷信息
     *
     * @throws IOException
     */
    private void getExam(int status) throws IOException {
        Map<String, Object> body = new HashMap<>();
        body.put("body", status);
        RequestMessage rm = new RequestMessage("exam", "getExamByStatus", body);
        JSONObject result = getResponseResult(rm);
        Object content = result.get("content");
        System.out.println("------------------------------------------");
        if (content.getClass().equals(JSONArray.class)) {
            JSONArray exams = (JSONArray) content;
            System.out.println("ID\t试卷名称\t科目\t状态");
            for (Object exam : exams) {
                JSONObject o = (JSONObject) exam;
                System.out.println(o.get("id") + "\t" + o.get("examName") + "\t" + o.get("categoryName") + "\t" + (o.get("status").toString().equals("0") ? "未发布" : "已发布"));
            }
        }
        System.out.println("------------------------------------------");
    }

    /**
     * 发布试卷
     *
     * @throws IOException
     */
    private void releaseExam() throws IOException {
        getExam(0);
        int examID = 0;
        while (true) {
            System.out.println("请输入要发布的试卷ID：");
            String input = CheneyScanner.reader.readLine();
            try {
                examID = Integer.parseInt(input);
                break;
            } catch (NumberFormatException e) {
                System.out.println("试卷ID输入错误，请重新输入！");
            }
        }
        Map<String, Object> body = new HashMap<>();
        body.put("body", examID);
        RequestMessage rm = new RequestMessage("exam", "releaseExam", body);
        JSONObject result = getResponseResult(rm);
        if (result.get("code").toString().equals("200")) {
            System.out.println("发布成功");
            getExam(1);
        } else {
            System.out.println(result.get("message").toString());
        }
    }

    /**
     * 发布试卷
     *
     * @throws IOException
     */
    private void recoveryExam() throws IOException {
        getExam(1);
        int examID = 0;
        while (true) {
            System.out.println("请输入要回收的试卷ID：");
            String input = CheneyScanner.reader.readLine();
            try {
                examID = Integer.parseInt(input);
                break;
            } catch (NumberFormatException e) {
                System.out.println("试卷ID输入错误，请重新输入！");
            }
        }
        Map<String, Object> body = new HashMap<>();
        body.put("body", examID);
        RequestMessage rm = new RequestMessage("exam", "recoveryExam", body);
        JSONObject result = getResponseResult(rm);
        if (result.get("code").toString().equals("200")) {
            System.out.println("回收成功");
            getExam(0);
        } else {
            System.out.println(result.get("message").toString());
        }
    }

    /**
     * 添加题目信息
     *
     * @throws IOException
     */
    private void addQuestion() throws IOException {
        int ExamID = 0;
        while (true) {
            System.out.println("请输入试卷ID");
            String examID = CheneyScanner.reader.readLine();
            try {
                ExamID = Integer.parseInt(examID);
                break;
            } catch (NumberFormatException e) {
                System.out.println("试卷ID格式输入有误，请重新输入！！");
            }
        }
        Map<String, Object> body = new HashMap<>();
        body.put("body", ExamID);
        RequestMessage rm = new RequestMessage("exam", "getExamById", body);
        JSONObject result = getResponseResult(rm);
        if (!result.get("code").toString().equals("200")) {
            System.out.println("输入的试卷未找到！");
            return;
        }
        JSONObject content = JSONObject.parseObject(result.get("content").toString());
        JSONArray questionsObject = (JSONArray) content.get("questions");
        JSONObject exam = new JSONObject();
        JSONArray questionArray = Optional.ofNullable(questionsObject).orElse(new JSONArray());
        while (true) {
            JSONObject question = new JSONObject();
            System.out.println("请输入题目：");
            String questionName = CheneyScanner.reader.readLine();
            int Score = 0;
            //录入试题分值
            while (true) {
                System.out.println("请输入题目分值：");
                String score = CheneyScanner.reader.readLine();
                try {
                    Score = Integer.parseInt(score);
                    break;
                } catch (NumberFormatException e) {
                    System.out.println("分值格式输入有误，请重新输入！！");
                }
            }
            //录入试题选项
            List<JSONObject> answerArray = new ArrayList<>();
            int option = 65;
            do {
                JSONObject answer = new JSONObject();
                System.out.println("请输入选项：");
                String optionValue = CheneyScanner.reader.readLine();
                answer.put("option", (char) option + "");
                answer.put("content", optionValue);
                answerArray.add(answer);
                System.out.println("是否继续添加选项？(y/n)");
                String isContinue = CheneyScanner.reader.readLine();
                if (isContinue.equalsIgnoreCase("n")) {
                    break;
                }
                option = option + 1;
            } while (option <= 90);
            //打印刚刚录入的选项，让用户选择正确选项
            List<String> optionList = new ArrayList<>();
            for (JSONObject jsonObject : answerArray) {
                System.out.println(jsonObject.get("option") + ":" + jsonObject.get("content"));
                optionList.add(jsonObject.get("option").toString());
            }
            //录入正确答案
            while (true) {
                System.out.println("输入正确答案选项：");
                String rightOption = CheneyScanner.reader.readLine();
                long count = optionList.stream().filter(s -> s.equals(rightOption)).count();
                if (count > 0) {
                    question.put("rightAnswer", rightOption);
                    break;
                }
                System.out.println("未匹配到对应的选项，请重新输入");
            }
            //构造对象
            question.put("name", questionName);
            question.put("score", Score);
            question.put("answers", answerArray);
            questionArray.add(question);
            System.out.println("是否继续录入试题？(y/n)");
            String isContinue = CheneyScanner.reader.readLine();
            if (isContinue.equalsIgnoreCase("n")) {
                break;
            }
        }
        exam.put("id", ExamID);
        exam.put("questions", questionArray);
        //因为exam其实是一个对象中不同属性的抽象HashMap 所以需要对它进行再次的包装成一个属性,并将body属性转换为JSON字符串
        body = new HashMap<>();
        body.put("body", JSON.toJSONString(exam));
        rm = new RequestMessage("exam", "updateExam", body);
        result = getResponseResult(rm);
        if (result.get("code").equals("200")) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }
    }

    /**
     * 获取试卷的试题
     *
     * @throws IOException
     */
    private int getQuestions() throws IOException {
        int examID = 0;
        while (true) {
            System.out.println("输入要查看试题的试卷ID：");
            String id = CheneyScanner.reader.readLine();
            try {
                examID = Integer.parseInt(id);
                break;
            } catch (NumberFormatException e) {
                System.out.println("试卷ID输入格式有误，请重新输入");
            }
        }
        Map<String, Object> body = new HashMap<>();
        body.put("body", examID);
        RequestMessage rm = new RequestMessage("exam", "getQuestions", body);
        JSONObject result = getResponseResult(rm);
        Object content = result.get("content");
        System.out.println("------------------------------------------");
        if (content.getClass().equals(JSONArray.class)) {
            JSONArray exams = (JSONArray) content;
            System.out.println("ID\t试题\t分值\t正确答案");
            for (Object exam : exams) {
                JSONObject o = (JSONObject) exam;
                System.out.println(o.get("id") + "\t" + o.get("name") + "\t" + o.get("score") + "\t" + o.get("rightAnswer"));
            }
        }
        return examID;
    }

    /**
     * 修改试卷试题
     *
     * @throws IOException
     */
    private void updateQuestion() throws IOException {
        int examID = getQuestions();
        int questionID = 0;
        while (true) {
            System.out.println("输入要修改试题的试题ID：");
            String id = CheneyScanner.reader.readLine();
            try {
                questionID = Integer.parseInt(id);
                break;
            } catch (NumberFormatException e) {
                System.out.println("试题ID输入格式有误，请重新输入");
            }
        }
        //封装参数发送服务端
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("examID", examID);
        body.put("questionID", questionID);
        RequestMessage rm = new RequestMessage("exam", "getQuestion", body);
        JSONObject result = getResponseResult(rm);
        if (result.get("code").toString().equals("200")) {
            JSONObject content = JSONObject.parseObject(result.get("content").toString());
            int Score = 0;
            String name = content.getString("name");
            String rightAnswer = content.getString("rightAnswer");
            String score = content.getString("score");
            JSONArray answers = content.getJSONArray("answers");
            System.out.println("试题题目内容为：" + name + "(是否修改y/n)");
            String choice = CheneyScanner.reader.readLine();
            if (choice.equalsIgnoreCase("y")) {
                System.out.println("请输入试题内容：");
                name = CheneyScanner.reader.readLine();
            }
            System.out.println("试题分值为：" + score + "(是否修改y/n)");
            choice = CheneyScanner.reader.readLine();
            if (choice.equalsIgnoreCase("y")) {
                while (true) {
                    System.out.println("请输入试题分数：");
                    score = CheneyScanner.reader.readLine();
                    try {
                        Score = Integer.parseInt(score);
                        break;
                    } catch (NumberFormatException e) {
                        System.out.println("分值格式输入有误，请重新输入");
                    }
                }
            }
            System.out.println("试题选项:");
            for (Object value : answers) {
                JSONObject answer = JSONObject.parseObject(value.toString());
                System.out.println("\t" + answer.get("option") + "：" + answer.get("content"));
            }
            System.out.println("(是否修改y/n)");
            choice = CheneyScanner.reader.readLine();
            if (choice.equalsIgnoreCase("y")) {
                do {
                    System.out.println("请输入要修改的选项：");
                    String option = CheneyScanner.reader.readLine();
                    AtomicInteger index = new AtomicInteger(0);
                    Optional<Object> queryOption = answers.stream().filter(s -> {
                        index.getAndIncrement();
                        return JSONObject.parseObject(s.toString()).get("option").toString().equals(option);
                    }).findFirst();
                    if (queryOption.isPresent()) {
                        System.out.println("请输入要修改的内容：");
                        String optionContent = CheneyScanner.reader.readLine();
                        JSONObject optionJsonObject = JSONObject.parseObject(queryOption.get().toString());
                        optionJsonObject.put("content", optionContent);
                        answers.set(index.get() - 1, optionJsonObject);
                        System.out.println("是否继续修改？（y/n）");
                    } else {
                        System.out.println("输入的选项有误，是否重新输入？（y/n）");
                    }
                    choice = CheneyScanner.reader.readLine();
                } while (!choice.equalsIgnoreCase("n"));
            }
            System.out.println("当前试题选项:");
            List<String> optionList = new ArrayList<>();
            for (Object o : answers) {
                JSONObject answer = JSONObject.parseObject(o.toString());
                optionList.add(answer.get("option").toString());
                System.out.println("\t" + answer.get("option") + "：" + answer.get("content"));
            }
            System.out.println("试题正确选项为：" + rightAnswer + "(是否修改y/n)");
            choice = CheneyScanner.reader.readLine();
            if (choice.equalsIgnoreCase("y")) {
                while (true) {
                    System.out.println("输入正确答案选项：");
                    String rightOption = CheneyScanner.reader.readLine();
                    long count = optionList.stream().filter(s -> s.equals(rightOption)).count();
                    if (count > 0) {
                        rightAnswer = rightOption;
                        break;
                    }
                    System.out.println("未匹配到对应的选项，请重新输入");
                }
            }
            content.put("name", name);
            content.put("rightAnswer", rightAnswer);
            content.put("score", score);
            content.put("answers", answers);
            body = new LinkedHashMap<>();
            body.put("examID", examID);
            body.put("questionID", questionID);
            body.put("data", JSON.toJSONString(content));
            rm = new RequestMessage("exam", "updateQuestion", body);
            result = getResponseResult(rm);
            if (result.get("code").toString().equals("200")) {
                System.out.println("修改成功");
            } else {
                System.out.println("修改失败");
            }
        } else {
            System.out.println("未检索到指定的试题信息");
        }
    }

    /**
     * 删除试题信息
     *
     * @throws IOException
     */
    private void deleteQuestion() throws IOException {
        int examID = getQuestions();
        int questionID = 0;
        while (true) {
            System.out.println("输入要删除试题的试题ID：");
            String id = CheneyScanner.reader.readLine();
            try {
                questionID = Integer.parseInt(id);
                break;
            } catch (NumberFormatException e) {
                System.out.println("试题ID输入格式有误，请重新输入");
            }
        }
        //封装参数发送服务端
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("examID", examID);
        body.put("questionID", questionID);
        RequestMessage rm = new RequestMessage("exam", "deleteQuestion", body);
        JSONObject result = getResponseResult(rm);
        if (result.get("code").toString().equals("200")) {
            System.out.println("删除成功");
        }
    }

    /**
     * 查看成绩
     *
     * @throws IOException
     */
    private void getExamAnswer() throws IOException {
        RequestMessage rm = new RequestMessage("userexamanswer", "getAllUserExamAnswers", null);
        JSONObject result = getResponseResult(rm);
        Object content = result.get("content");
        if (content.getClass().equals(JSONArray.class)) {
            JSONArray exams = (JSONArray) content;
            if (exams.size() == 0) {
                System.out.println("暂无考试成绩！");
                return;
            } else {
                System.out.println("学生姓名\t试卷名称\t科目\t成绩");
                for (Object exam : exams) {
                    JSONObject o = (JSONObject) exam;
                    System.out.println(o.get("userName") + "\t" + o.get("examName") + "\t" + o.get("categoryName") + "\t" + o.get("sumScore").toString());
                }
            }
        }
    }

    /**
     * 发送数据并等待回复数据
     *
     * @param rm
     * @return
     * @throws IOException
     */
    private JSONObject getResponseResult(RequestMessage rm) throws IOException {
        super.getOut().println(JSON.toJSONString(rm));
        String readLine = super.getIn().readLine();
        return JSON.parseObject(readLine);
    }
}
